import {
	sendSmsCode,
	generalLogin,
	codeLogin,
	logout
} from '@/api/login/login.js'
import {
	userInfo
} from '@/api/user/user.js'

const TOKEN_EXPIRE_TIME = 24 * 60 * 60 * 1000 * 7 // 24小时（毫秒）
const TOKEN_BUFFER_TIME = 5 * 60 * 1000 // 提前5分钟视为过期（毫秒）

const storage = {
	set: (key, value) => {
		try {
			const storageValue = typeof value === 'object' ? JSON.stringify(value) : value
			uni.setStorageSync(key, storageValue)
		} catch (e) {
			console.error('存储失败:', e)
		}
	},
	get: (key) => {
		try {
			const value = uni.getStorageSync(key)
			try {
				return value ? JSON.parse(value) : null
			} catch {
				return value
			}
		} catch (e) {
			console.error('读取存储失败:', e)
			return null
		}
	},
	remove: (key) => {
		try {
			uni.removeStorageSync(key)
		} catch (e) {
			console.error('删除存储失败:', e)
		}
	},
	clearUserData: () => {
		const keys = ['token', 'userInfo', 'token_timestamp']
		keys.forEach(key => {
			try {
				uni.removeStorageSync(key)
			} catch (e) {
				console.error(`删除 ${key} 失败:`, e)
			}
		})
	}
}

const tokenUtils = {
	// 计算 token 过期时间
	getTokenExpireTime: (loginTimestamp) => {
		return loginTimestamp + TOKEN_EXPIRE_TIME - TOKEN_BUFFER_TIME
	},
	
	// 检查 token 是否过期
	isTokenExpired: (loginTimestamp) => {
		if (!loginTimestamp) return true
		const expireTime = tokenUtils.getTokenExpireTime(loginTimestamp)
		return Date.now() >= expireTime
	},
	
	// 检查 token 是否即将过期（5分钟内）
	isTokenExpiringSoon: (loginTimestamp) => {
		if (!loginTimestamp) return false
		const expireTime = tokenUtils.getTokenExpireTime(loginTimestamp)
		const timeLeft = expireTime - Date.now()
		return timeLeft > 0 && timeLeft < 5 * 60 * 1000
	}
}

// 初始化状态 - 从持久化存储恢复
const getInitialState = () => {
	const token = storage.get('token')
	const userInfo = storage.get('userInfo')
	const tokenTimestamp = storage.get('token_timestamp')
	
	// 检查 token 是否过期
	const isTokenValid = token && tokenTimestamp && !tokenUtils.isTokenExpired(tokenTimestamp)
	
	return {
		token: isTokenValid ? token : null,
		userInfo: isTokenValid ? userInfo : null,
		tokenTimestamp: isTokenValid ? tokenTimestamp : null,
		// 验证码倒计时状态
		smsTimer: {
			isTime: false,
			timesNum: 60
		}
	}
}

const state = getInitialState()

const mutations = {
	SET_TOKEN(state, token) {
		state.token = token
		state.tokenTimestamp = Date.now() // 记录登录时间戳
		
		// 持久化存储
		storage.set('token', token)
		storage.set('token_timestamp', state.tokenTimestamp)
	},
	
	CLEAR_TOKEN(state) {
		state.token = null
		state.tokenTimestamp = null
		storage.remove('token')
		storage.remove('token_timestamp')
	},
	
	SET_USER_INFO(state, userInfo) {
		state.userInfo = userInfo
		storage.set('userInfo', userInfo)
	},
	
	CLEAR_USER_INFO(state) {
		state.userInfo = null
		storage.remove('userInfo')
	},
	
	// 更新验证码倒计时状态
	SET_SMS_TIMER(state, timerData) {
		state.smsTimer = {
			...state.smsTimer,
			...timerData
		}
	},
	
	// 刷新 token 时间戳（用于活跃用户延长 token 有效期）
	REFRESH_TOKEN_TIMESTAMP(state) {
		if (state.token) {
			state.tokenTimestamp = Date.now()
			storage.set('token_timestamp', state.tokenTimestamp)
		}
	}
}

const actions = {
	/**
	 * 初始化应用状态 
	 */
	async initializeApp({ commit, dispatch, state }) {
		try {
			// 如果存在有效 token 但用户信息为空，尝试获取用户信息
			if (state.token && !state.userInfo) {
				await dispatch('getUserInfo')
			}
			
			// 检查 token 是否即将过期
			if (tokenUtils.isTokenExpiringSoon(state.tokenTimestamp)) {
				console.log('Token 即将过期，请重新登录')
			}
			
			return {
				isLoggedIn: !!state.token && !tokenUtils.isTokenExpired(state.tokenTimestamp),
				message: state.token ? '状态恢复成功' : '未登录状态'
			}
		} catch (error) {
			console.error('初始化应用失败:', error)
			// 初始化失败时清除可能无效的状态
			dispatch('clearLoginState')
			throw error
		}
	},
	
	/**
	 * 清除登录状态
	 */
	clearLoginState({ commit }) {
		commit('CLEAR_TOKEN')
		commit('CLEAR_USER_INFO')
		storage.clearUserData()
	},
	
	/**
	 * 发送短信验证码
	 */
	sendSmsCode({ commit, state }, mobile) {
		if (state.smsTimer.isTime) return Promise.reject(new Error('倒计时中，请勿重复发送'))

		return new Promise(async (resolve, reject) => {
			try {
				await sendSmsCode({ mobile }) 

				// 启动倒计时
				commit('SET_SMS_TIMER', {
					isTime: true,
					timesNum: 60
				})
				
				let count = 60
				const timer = setInterval(() => {
					count--
					commit('SET_SMS_TIMER', { timesNum: count })

					if (count <= 0) {
						clearInterval(timer)
						commit('SET_SMS_TIMER', {
							isTime: false,
							timesNum: 60
						})
					}
				}, 1000)

				resolve('验证码发送成功')
			} catch (error) {
				console.error('发送验证码失败:', error)
				reject(error.message || '验证码发送失败')
			}
		})
	},

	/**
	 * 验证码登录
	 */
	async codeLogin({ commit, dispatch }, loginData) {
		try {
			const { data } = await codeLogin(loginData)
			
			if (!data || !data.token) {
				throw new Error('登录响应数据异常')
			}
			
			// 存储 Token
			commit('SET_TOKEN', data.token)
			
			// 获取用户信息
			await dispatch('getUserInfo')
			return {
				success: true,
				message: '登录成功',
				token: data.token
			}
		} catch (error) {
			// 登录失败时清除可能存在的无效 token
			dispatch('clearLoginState')
			throw new Error(error.message || '登录失败，请重试')
		}
	},

	/**
	 * 密码登录
	 */
	async passwordLogin({ commit, dispatch }, loginData) {
		try {
			const res = await generalLogin(loginData)
			
			if (!res.data || !res.data.token) {
				throw new Error('登录响应数据异常')
			}
			
			// 存储 Token
			commit('SET_TOKEN', res.data.token)
			
			// 获取用户信息
			await dispatch('getUserInfo')
			return {
				success: true,
				message: '登录成功',
				token: res.data.token
			}
		} catch (error) {
			dispatch('clearLoginState')
			throw new Error(error.message || '登录失败，请检查账号密码')
		}
	},

	/**
	 * 获取用户信息
	 */
	async getUserInfo({ commit, state, dispatch }) {
		// 检查 token 是否有效
		if (!state.token || tokenUtils.isTokenExpired(state.tokenTimestamp)) {
			dispatch('clearLoginState')
			throw new Error('登录已过期，请重新登录')
		}

		try {
			const { data } = await userInfo()
			commit('SET_USER_INFO', data)
			
			// 成功获取用户信息后，刷新 token 时间戳
			// commit('REFRESH_TOKEN_TIMESTAMP')
			
			return data
		} catch (error) {
			console.error('获取用户信息失败:', error)
			
			// 如果是 token 失效的错误码，清除登录状态
			if (error.code === 401 || error.status === 401) {
				dispatch('clearLoginState')
				throw new Error('登录已过期，请重新登录')
			}
			
			throw new Error(error.message || '用户信息获取失败')
		}
	},

	/**
	 * 退出登录
	 */
	async getLogout({ commit, state, dispatch }) {
		try {
			// 如果有有效 token，调用后端退出接口
			if (state.token && !tokenUtils.isTokenExpired(state.tokenTimestamp)) {
				await logout().catch(err => {
					console.warn('后端退出接口调用失败:', err)
					// 即使后端退出失败，也继续执行前端退出逻辑
				})
			}
		} catch (error) {
			console.warn('退出登录接口异常:', error)
		} finally {
			// 无论如何都清除前端状态
			dispatch('clearLoginState')
			
			// 重置验证码倒计时
			commit('SET_SMS_TIMER', {
				isTime: false,
				timesNum: 60
			})
		}
		
		return '退出登录成功'
	},
	
	/**
	 * 检查登录状态
	 */
	checkLoginStatus({ state }) {
		return !!state.token && !tokenUtils.isTokenExpired(state.tokenTimestamp)
	},
	
	/**
	 * 刷新 token 时间戳（用于用户活跃时延长有效期）
	 */
	refreshTokenTimestamp({ commit, state }) {
		if (state.token && !tokenUtils.isTokenExpired(state.tokenTimestamp)) {
			commit('REFRESH_TOKEN_TIMESTAMP')
			return true
		}
		return false
	}
}

const getters = {
	token: state => state.token,
	userInfo: state => state.userInfo,
	
	// 实时计算登录状态
	isAuthenticated: state => {
		return !!state.token && !tokenUtils.isTokenExpired(state.tokenTimestamp)
	},
	
	// token 剩余有效时间（毫秒）
	tokenTimeLeft: state => {
		if (!state.tokenTimestamp) return 0
		const expireTime = tokenUtils.getTokenExpireTime(state.tokenTimestamp)
		return Math.max(0, expireTime - Date.now())
	},
	
	// token 是否即将过期（5分钟内）
	tokenExpiringSoon: state => {
		return tokenUtils.isTokenExpiringSoon(state.tokenTimestamp)
	},
	
	smsTimer: state => state.smsTimer,
	
	// 登录时间（用于显示）
	loginTime: state => {
		return state.tokenTimestamp ? new Date(state.tokenTimestamp) : null
	}
}

export default {
	namespaced: true,
	state,
	mutations,
	actions,
	getters
}